package com.wang.di.utils;

import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;

// di注入相关的工具函数
public class DIUtils {
    // 获取包下的所有带注解的类
    public static List<Class<?>> all(Class<?> accessClz) throws IOException, ClassNotFoundException {
        ClassLoader cl = accessClz.getClassLoader();
        Enumeration<URL> it = cl.getResources(accessClz.getPackage().getName().replace('.', '/'));
        String pkgName = accessClz.getPackage().getName();
        List<Class<?>> list = new LinkedList<>();

        while (it.hasMoreElements()) {
            URL url = it.nextElement();
            String protocol = url.getProtocol();
            if (protocol.equals("file")) {
                File clzFile = new File(url.getPath());
                list.addAll(allClazz(cl, clzFile, pkgName));
            } else if (protocol.equals("jar")) {
                // todo: 从jar包中获取文件
            } else {
                System.err.println("it is not defined: " + protocol);
            }
        }
        list.removeIf(c -> c.getAnnotations().length == 0);
        return list;
    }

    private static List<Class<?>> allClazz(ClassLoader clzLoader, File dir, String pkg) throws ClassNotFoundException {
        List<Class<?>> list = new LinkedList<>();
        if (dir.listFiles() == null) return list;
        for (File sub : dir.listFiles()) {
            if (sub.isDirectory()) {
                list.addAll(allClazz(clzLoader, sub, pkg + "." + sub.getName()));
            } else if (sub.getName().endsWith(".class")) {
                String clzName = sub.getName().substring(0, sub.getName().indexOf('.'));
                String clzAllName = pkg + "." + clzName;
                list.add(clzLoader.loadClass(clzAllName));
            }
        }
        return list;
    }
}
